/**
 * Copyright 2002-2010 the original author or authors.
 */
package com.dwusoft.platform.template;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.apache.rpc.util.ToolsUtil;

/**
 * 对文件的删除、剪切、移动和创建文件夹操作
 * 
 * @author Hou Dayu
 */
public class FileOperateUtil {

	private static Logger log = Logger.getLogger(FileOperateUtil.class);

	/**
	 * 检查文件或文件夹是否存在
	 * 
	 * @param folderPath  文件或文件夹路径
	 * @return            true为存在，false不存在
	 */
	public static boolean checkFolder(String folderPath) {
		boolean result = false;
		if (ToolsUtil.isNotNull(folderPath)) {
			File newFilePath = new File(folderPath);
			result = newFilePath.exists();
		}
		return result;
	}

	/**
	 * 取指定文件夹中的文件的数量
	 * 
	 * @param path            文件夹路径
	 * @param fileNamePrefix  文件名前缀
	 * @return
	 */
	public static int getFileNumber(String path, String fileNamePrefix) {
		int fileCount = 0;
		if (ToolsUtil.isNotNull(path)) {
			File d = new File(path);
			File list[] = d.listFiles();
			for (int i = 0; i < list.length; i++) {
				if (list[i].isFile()) {
					if (ToolsUtil.isNotNull(fileNamePrefix)) {
						if (list[i].getName().indexOf(fileNamePrefix) != -1)
							fileCount++;
					} else
						fileCount++;
				}
			}
		}
		return fileCount;
	}

	/**
	 * 新建目录操作
	 * 
	 * @param folderPath 文件夹路径
	 */
	public static boolean newCreateFolder(String folderPath) {
		boolean result = false;
		try {
			if (ToolsUtil.isNotNull(folderPath)) {
				File newFilePath = new File(folderPath);
				if (!newFilePath.exists()) {
					result = newFilePath.mkdirs();
				}
			}
		} catch (Exception e) {
			log.error("新建目录操作出错ERROR KEY:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 创建新的文件
	 * 
	 * @param filePathAndName 文件名称
	 * @param fileContent     文件内容
	 */
	public static boolean newCreateFile(String filePathAndName, String fileContent) {
		boolean result = false;
		try {
			if (ToolsUtil.isNotNull(filePathAndName)) {
				File newFilePath = new File(filePathAndName);
				if (!newFilePath.exists()) {
					newFilePath.createNewFile();
				}
				FileUtils.writeStringToFile(newFilePath, fileContent);
				result = true;
			}
		} catch (Exception e) {
			log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 创建新的文件
	 * 
	 * @param filePathAndName 文件名称
	 * @param fileContent     文件内容
	 */
	public static boolean newCreateFile(String filePathAndName, String fileContent, String encoding) {
		boolean result = false;
		try {
			if (ToolsUtil.isNotNull(filePathAndName)) {
				File newFilePath = new File(filePathAndName);
				if (!newFilePath.exists()) {
					newFilePath.createNewFile();
				}
				FileUtils.writeStringToFile(newFilePath, fileContent, encoding);
				result = true;
			}
		} catch (Exception e) {
			log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 创建新的文件
	 * 
	 * @param inputStream 文件内容流
	 * @param filePath    文件路径
	 * @return            返回true为创建成功，false为创建失败
	 */
	public static boolean newCreateFile(InputStream inputStream, String filePath) {
		boolean result = false;
		if (inputStream == null)
			return false;
		FileOutputStream output = null;
		try {
			if (checkFolder(filePath))
				delFile(filePath);
			output = new FileOutputStream(filePath);
			byte[] buffer = new byte[1024];
			int bytesRead = 0;

			while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {
				output.write(buffer, 0, bytesRead);
			}
			result = true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
		} finally {
			try {
				if (output != null) {
					output.flush();
					output.close();
				}
				inputStream.close();
			} catch (Exception e) {
				log.error("关闭文件流出错ERROR KEY:" + e.getMessage());
			}
		}
		return result;
	}

	/**
	 * 删除文件
	 * 
	 * @param filePathAndName 文件路径名称
	 * @return                true删除成功，false删除失败
	 */
	public static boolean delFile(String filePathAndName) {
		boolean result = false;
		try {
			if (ToolsUtil.isNotNull(filePathAndName)) {
				if (checkFolder(filePathAndName)) {
					File delFile = new File(filePathAndName);
					result = delFile.delete();
				}
				result = true;
			}
		} catch (Exception e) {
			log.error("删除文件操作出错ERROR KEY:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 删除文件夹
	 * 
	 * @param folderPath      文件夹路径
	 * @param isDelFolderPath 是否删除文件夹目录。
	 * @return                true删除，false不删除。
	 */
	public static void delFolder(String folderPath, boolean isDelFolderPath) {
		try {
			if (ToolsUtil.isNotNull(folderPath)) {
				delAllFile(folderPath);//删除完里面所有内容    
				if (isDelFolderPath) {
					File delFilePath = new File(folderPath);
					delFilePath.delete(); //删除空文件夹     
				}
			}
		} catch (Exception e) {
			log.error("删除文件夹操作出错ERROR KEY:" + e.getMessage());
		}
	}

	/**
	 * 批量删除文件
	 * 
	 * @param path 文件所在目录
	 * @return     true删除成功，false删除失败
	 */
	public static boolean delAllFile(String path) {
		if (ToolsUtil.isNull(path))
			return false;
		File file = new File(path);
		if (!file.exists()) {
			return false;
		}
		if (!file.isDirectory()) {
			return false;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				//删除文件夹里面的文件
				delAllFile(path + "/" + tempList[i]);
				delFolder(path + "/" + tempList[i], true);//删除空文件夹     
			}
		}
		return true;
	}

	/**
	 * 删除文件夹
	 * 
	 * @param folderPath      文件夹路径
	 * @param isDelFolderPath 是否删除文件夹目录。
	 * @return                返回删除成功和失败的数量集合
	 */
	public static Map<String, String> delFolder(String folderPath, Map<String, String> map) {
		try {
			if (ToolsUtil.isNotNull(folderPath)) {
				map = delAllFile(folderPath, map);//删除完里面所有内容    
				File delFilePath = new File(folderPath);
				delFilePath.delete(); //删除空文件夹     
			}
		} catch (Exception e) {
			log.error("删除文件夹操作出错ERROR KEY:" + e.getMessage());
		}
		if (ToolsUtil.isEmpty(map))
			map = new HashMap<String, String>();
		return map;
	}

	/**
	 * 批量删除文件
	 * 
	 * @param path 文件所在目录
	 * @param map  删除成功和失败的数量集合
	 * @return     返回删除成功和失败的数量集合
	 */
	public static Map<String, String> delAllFile(String path, Map<String, String> map) {
		if (ToolsUtil.isNull(path))
			return null;
		File file = new File(path);
		if (!file.exists()) {
			return null;
		}
		if (!file.isDirectory()) {
			return null;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			map = getDelFileMap(temp, map);
			if (temp.isDirectory()) {
				//删除文件夹里面的文件
				map = delAllFile(path + "/" + tempList[i], map);
				map = delFolder(path + "/" + tempList[i], map);//删除空文件夹     
			}
		}
		return map;
	}

	/**
	 * 复制文件到指定目录
	 * 
	 * @param oldPath 源路径
	 * @param newPath 新路径
	 * @return        true复制成功，false复制失败
	 */
	public static boolean copyFile(String oldPath, String newPath) {
		boolean result = false;
		try {
			if (ToolsUtil.isNotNull(oldPath) && ToolsUtil.isNotNull(newPath)) {

				//统一配置后，两个path一样，所以屏蔽要复制的文件与原文件属于同一个父节点错误
				if (oldPath.equalsIgnoreCase(newPath)) {
					return true;
				}
				File oldfile = new File(oldPath);
				if (oldfile.exists()) { //文件存在时
					FileUtils.copyFile(oldfile, new File(newPath));
				}
				result = true;
			}
		} catch (Exception e) {
			log.error("复制文件操作出错ERROR KEY:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 复制整个文件夹及内容
	 * 
	 * @param oldPath 源路径
	 * @param newPath 新路径
	 * @param type    不需要复制的文件（如html,jsp,asp,shtml,htm...）
	 */
	public static void copyFolder(String oldPath, String newPath, String type) {
		try {
			if (ToolsUtil.isNotNull(oldPath) && ToolsUtil.isNotNull(newPath)) {
				if (oldPath.equalsIgnoreCase(newPath)) {
					return;
				}
				newCreateFolder(newPath);//如果文件夹不存在 则建立新文件夹     
				File oldFilePath = new File(oldPath);
				FileUtils.copyDirectory(oldFilePath, new File(newPath), true);
			}
		} catch (Exception e) {
			log.error("复制整个文件夹内容操作出错 ERROR KEY:" + e.getMessage());
		}
	}

	/**
	 * 复制整个文件夹及内容
	 * 
	 * @param filePath    源文件存放地址
	 * @param newFilePath 复制后存放的地址
	 */
	public static void copyFiles(String filePath, String newFilePath) {
		if (ToolsUtil.isNotNull(filePath) && ToolsUtil.isNotNull(newFilePath)) {
			//统一配置后，两个path一样，所以屏蔽要复制的文件与原文件属于同一个父节点错误
			if (filePath.equalsIgnoreCase(newFilePath)) {
				return;
			}

			LinkedList<File> list = new LinkedList<File>();
			Map<String, String> filePaths = new HashMap<String, String>();
			newCreateFolder(filePath);
			File file = new File(filePath);
			if (file.exists()) {
				newCreateFolder(newFilePath);
				if (file.isDirectory()) {
					File[] fileArray = file.listFiles();
					if (!ToolsUtil.isNull(fileArray)) {
						for (int i = 0; i < fileArray.length; i++) {
							if (fileArray[i].isDirectory()) {
								String path = newFilePath + "/" + fileArray[i].getName();
								newCreateFolder(path);
								filePaths.put(fileArray[i].getPath(), path);
								list.add(fileArray[i]);
							} else {
								copyFile(fileArray[i].toString(), newFilePath + "/" + fileArray[i].getName().toString());
							}
						}
					}
					copyFiles(filePaths, list);
				} else
					copyFile(file.toString(), newFilePath + "/" + file.getName().toString());
			} else
				log.error("The File/Folder doesn't exist!");
		}
	}

	/**
	 * 如果folderPath为文件路径，则将该文件变成一个空文件。<br>
	 * 如果folderPath是文件夹路径，则将其下的所有文件都变成空文件。
	 * 
	 * @param folderPath
	 *            文件或文件夹的绝对路径
	 */
	public static void fileToEmpty(String folderPath) {
		LinkedList<File> list = new LinkedList<File>();
		File file = new File(folderPath);
		if (file.exists()) {
			if (file.isDirectory()) {
				File[] fileArray = file.listFiles();
				if (!ToolsUtil.isNull(fileArray)) {
					for (int i = 0; i < fileArray.length; i++) {
						if (fileArray[i].isDirectory()) {
							list.add(fileArray[i]);
						} else {
							fileArray[i].delete();
							newCreateFile(fileArray[i].getPath(), "");
						}
					}
				}
				fileToEmpty(list);
			} else {
				file.delete();
				newCreateFile(folderPath, "");
			}
		} else
			log.error("The File/Folder doesn't exist!");
	}

	/**
	 * 取目录文件个数
	 * 
	 * @param f 文件目录
	 * @return  返回指定目录中文件的个数
	 */
	public static long getlist(File f) {
		long size = 0;
		File flist[] = f.listFiles();
		size = flist.length;
		for (int i = 0; i < flist.length; i++) {
			if (flist[i].isDirectory()) {
				size--;
			}
		}
		return size;
	}

	/**
	 * 移动文件
	 * 
	 * @param oldPath 源路径
	 * @param newPath 目标路径
	 */
	public static void moveFile(String oldPath, String newPath) {
		copyFile(oldPath, newPath);
		delFile(oldPath);

	}

	/**
	 * 移动文件夹及文件
	 * 
	 * @param oldPath   源路径
	 * @param newPath   目标路径
	 * @param isOldPath 是否删除源路径
	 */
	public static void moveFolder(String oldPath, String newPath, boolean isOldPath) {
		copyFiles(oldPath, newPath);
		delFolder(oldPath, isOldPath);
	}

	/**
	 * 内容页上一页，下一页字符串生成方法
	 * 
	 * @param savePath 文件保存路径
	 * @param fileName 文件名子
	 * @param content  方件内容
	 * */
	public static void WriteJs(String savePath, String fileName, String content) {
		newCreateFolder(savePath);
		FileOutputStream fo;
		try {
			fo = new FileOutputStream(savePath + fileName);//"content_page.js");
			OutputStreamWriter osw = new OutputStreamWriter(fo, "UTF-8");
			PrintWriter out1 = new PrintWriter(osw);
			out1.println(content);
			out1.close();
			osw.close();
			fo.close();
		} catch (Exception e) {
			log.error("生成文件" + fileName + "出错ERROR KEY:" + e.getMessage());
		}
	}

	/**
	 * 修改内容页上一页，下一页字符串
	 * 
	 * @param contPath 文件存放路径
	 * @param fileName 文件名子
	 * @param docId    稿件ID
	 * @param title    稿件标题
	 * @param url      稿件URL
	 */
	public static String getContentManager(String fileName) throws Exception {
		File file = new File(fileName);
		if (file.exists())
			return FileUtils.readFileToString(new File(fileName), "UTF-8");
		else
			return "";
	}

	/**
	 * 修改Property文件
	 * 
	 * @param pathName     文件全路径
	 * @param taskId       主任务ID
	 * @param resourcePath 要写入的值
	 * @param isfalg       true为新增内容，false为清楚内容
	 * @param key          property的KEY的名称
	 */
	public static void removePropertyContent(String pathName, String taskId, String resourcePath, boolean isfalg,
			String key) {
		StringBuffer result = new StringBuffer();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(pathName), "utf8"));
			while (br.ready()) {
				String str = br.readLine();
				if (isfalg)
					result.append(str + "\n");
				else {//清除无用的参数
					if (str.indexOf(taskId) == -1)
						result.append(str + "\n");
				}
			}
			br.close();
			if (isfalg)
				result.append(key + "=" + resourcePath);
			newCreateFile(pathName, result.toString());
		} catch (Exception e) {
			log.error("property文件夹操作出错ERROR KEY:" + e.getMessage());
		}
	}

	/**
	 * 获取文件
	 * 
	 * @param fileName 文件名
	 * @param oldPath  源文件路径
	 * @param type     要过滤的文件类型
	 * @return         返回指定的文件
	 */
	private static File getFile(String fileName, String oldPath, String type) {
		File temp = null;
		boolean falg = false;
		if (fileName.toUpperCase().indexOf("." + type) != -1) {
			falg = true;
		} else {
			falg = fileName.toUpperCase().indexOf(".zip") != -1;//排除指定类型的文件
		}
		if (oldPath.endsWith(File.separator)) {
			if (!falg)
				temp = new File(oldPath + fileName);
			else
				temp = null;
		} else {
			if (!falg)
				temp = new File(oldPath + File.separator + fileName);
			else
				temp = null;
		}
		return temp;
	}

	/**
	 * 复制整个文件夹及内容
	 * 
	 * @param filePaths 目标文件目录集合
	 * @param list      源文件目录集合
	 */
	private static void copyFiles(Map<String, String> filePaths, LinkedList<File> list) {
		while (!list.isEmpty()) {
			File fileInList = list.removeFirst();
			if (fileInList.isDirectory()) {
				File[] fileArray = fileInList.listFiles();
				if (fileArray == null)
					return;
				for (int i = 0; i < fileArray.length; i++) {
					if (fileArray[i].isDirectory()) {
						//如果文件夹不存在 则建立新文件夹   
						String paths = filePaths.get(fileInList.getPath()) + "/" + fileArray[i].getName();
						newCreateFolder(paths);
						list.add(fileArray[i]);
						filePaths.put(fileArray[i].getPath(), paths);
					} else {
						copyFile(fileArray[i].toString(),
								filePaths.get(fileInList.getPath()) + "/" + fileArray[i].getName());
					}
				}
			}
		}
	}

	/**
	 * 清空整个文件夹中的文件内容
	 * 
	 * @param list  源文件目录集合
	 */
	private static void fileToEmpty(LinkedList<File> list) {
		while (!list.isEmpty()) {
			File fileInList = list.removeFirst();
			if (fileInList.isDirectory()) {
				File[] fileArray = fileInList.listFiles();
				if (fileArray == null)
					return;
				for (int i = 0; i < fileArray.length; i++) {
					if (fileArray[i].isDirectory()) {
						//如果文件夹不存在 则建立新文件夹   
						list.add(fileArray[i]);
					} else {
						fileArray[i].delete();
						newCreateFile(fileArray[i].getPath(), "");
					}
				}
			} else {
				fileInList.delete();
				newCreateFile(fileInList.getPath(), "");
			}
		}
	}

	/**
	 * 获取删除文件的数量
	 * 
	 * @param temp 文件对象
	 * @param map  存储集合
	 * @return     返回删除文件的数量集合
	 */
	private static Map<String, String> getDelFileMap(File temp, Map<String, String> map) {
		int susNum = 0, errorNum = 0;
		if (temp.isFile()) {
			boolean falg = temp.delete();
			if (falg) {
				if (!ToolsUtil.isEmpty(map.get("susm")))
					susNum = Integer.parseInt(map.get("susm"));
				if (temp.getName().indexOf(".html") != -1 || temp.getName().indexOf(".shtml") != -1)
					susNum++;
				map.put("susm", String.valueOf(susNum));
			} else {
				errorNum++;
				if (!ToolsUtil.isEmpty(map.get("error")))
					errorNum = errorNum + Integer.parseInt(map.get("error"));
				map.put("error", String.valueOf(errorNum));
			}
		}
		return map;
	}

	/**
	 * 修改文件名称
	 * 
	 * @param filePath   文件件全路径
	 * @param namePrefix 新名前缀
	 * @param flag       true为添加对应的名称前缀,false为去掉对应的名称前缀
	 * @return           true为名称修改成功，false为名称修改失败
	 */
	public static boolean reFileName(String filePath, String namePrefix, boolean flag) {
		boolean mark = false;
		if (ToolsUtil.isNotNull(filePath) && ToolsUtil.isNotNull(namePrefix)) {
			File file = new File(filePath);
			if (file.isFile()) {
				String fileName = file.getName();
				String path = file.getPath();
				path = path.replace(fileName, "");
				if (flag) {
					fileName = namePrefix + "_" + fileName;
				} else {
					fileName = fileName.replace(namePrefix + "_", "");
				}
				mark = file.renameTo(new File(path + fileName)); //改名  
			}
		}
		return mark;
	}

	/**
	 * 格式化文件路径
	 *
	 * @param path 文件路径
	 * @return
	 */
	public static String getFormatFilePath(String path) {
		if (ToolsUtil.isNull(path))
			return "";
		path = path.replace("\\", "/");
		return path.replace("//", "/");
	}

	/**
	 * 随即生成最大值以内的随机数
	 * 
	 * @param  maxNum 设定的随即最大数值
	 * @return        返回随即最大限制以内的随机值
	 */
	public static String getRandomNumber(int maxNum) {
		int intRd = 0; //存放随机数
		Random rdm = new Random();
		for (int i = 0; i < maxNum; i++) {
			int randomValue = rdm.nextInt();
			if (randomValue == Integer.MIN_VALUE)
				randomValue = Integer.MAX_VALUE;
			intRd = Math.abs(randomValue) % maxNum + 1;
		}
		String num = "";
		num = String.valueOf(intRd);
		return num;
	}
}
